diff --git a/pkg/api/pluginproxy/ds_proxy.go b/pkg/api/pluginproxy/ds_proxy.go
index 35c1ca2..4c0bcc1 100644
--- a/pkg/api/pluginproxy/ds_proxy.go
+++ b/pkg/api/pluginproxy/ds_proxy.go
@@ -223,12 +223,6 @@ func (proxy *DataSourceProxy) director(req *http.Request) {
 			password))
 	}
 
-	dsAuth := req.Header.Get("X-DS-Authorization")
-	if len(dsAuth) > 0 {
-		req.Header.Del("X-DS-Authorization")
-		req.Header.Set("Authorization", dsAuth)
-	}
-
 	proxyutil.ApplyUserHeader(proxy.cfg.SendUserHeader, req, proxy.ctx.SignedInUser)
 
 	proxyutil.ClearCookieHeader(req, proxy.ds.AllowedCookies(), []string{proxy.cfg.LoginCookieName})
diff --git a/pkg/services/contexthandler/model/model.go b/pkg/services/contexthandler/model/model.go
index 679b68a..6722436 100644
--- a/pkg/services/contexthandler/model/model.go
+++ b/pkg/services/contexthandler/model/model.go
@@ -179,3 +179,11 @@ func (ctx *ReqContext) QueryBoolWithDefault(field string, d bool) bool {
 
 	return ctx.QueryBool(field)
 }
+
+const (
+	dsAuthorizationHeaderName = "X-Ds-Authorization"
+)
+
+func (ctx *ReqContext) GetDsAuthorization() (string, string) {
+	return dsAuthorizationHeaderName, ctx.Req.Header.Get(dsAuthorizationHeaderName)
+}
diff --git a/pkg/services/ngalert/api/util.go b/pkg/services/ngalert/api/util.go
index 00691a9..293ad6e 100644
--- a/pkg/services/ngalert/api/util.go
+++ b/pkg/services/ngalert/api/util.go
@@ -114,6 +114,11 @@ func (p *AlertingProxy) withReq(
 	for h, v := range headers {
 		req.Header.Add(h, v)
 	}
+	dsAuthHeader, dsAuthHeaderValue := ctx.GetDsAuthorization()
+	if dsAuthHeaderValue != "" {
+		req.Header.Add(dsAuthHeader, dsAuthHeaderValue)
+	}
+
 	// this response will be populated by the response from the datasource
 	resp := response.CreateNormalResponse(make(http.Header), nil, 0)
 	proxyContext := p.createProxyContext(ctx, req, resp)
diff --git a/pkg/services/pluginsintegration/clientmiddleware/datasource_authorization_middleware.go b/pkg/services/pluginsintegration/clientmiddleware/datasource_authorization_middleware.go
new file mode 100644
index 0000000..9ef6fce
--- /dev/null
+++ b/pkg/services/pluginsintegration/clientmiddleware/datasource_authorization_middleware.go
@@ -0,0 +1,80 @@
+package clientmiddleware
+
+import (
+	"context"
+
+	"github.com/grafana/grafana-plugin-sdk-go/backend"
+	"github.com/grafana/grafana/pkg/plugins"
+	"github.com/grafana/grafana/pkg/services/contexthandler"
+)
+
+// NewDatasourceAuthorizationMiddleware creates a new plugins.ClientMiddleware that will
+// forward incoming datasource authorization HTTP request header to outgoing plugins.Client requests
+func NewDatasourceAuthorizationMiddleware() plugins.ClientMiddleware {
+	return plugins.ClientMiddlewareFunc(func(next plugins.Client) plugins.Client {
+		return &DatasourceAuthorizationMiddleware{
+			next: next,
+		}
+	})
+}
+
+type DatasourceAuthorizationMiddleware struct {
+	next plugins.Client
+}
+
+func (m *DatasourceAuthorizationMiddleware) applyAuthorizationHeader(ctx context.Context, req backend.ForwardHTTPHeaders) {
+	reqCtx := contexthandler.FromContext(ctx)
+	// If no HTTP request context then skip middleware.
+	if req == nil || reqCtx == nil || reqCtx.Req == nil {
+		return
+	}
+
+	dsAuthHeader, dsAuthHeaderValue := reqCtx.GetDsAuthorization()
+	if dsAuthHeaderValue != "" {
+		req.SetHTTPHeader(dsAuthHeader, dsAuthHeaderValue)
+	}
+	return
+}
+
+func (m *DatasourceAuthorizationMiddleware) QueryData(ctx context.Context, req *backend.QueryDataRequest) (*backend.QueryDataResponse, error) {
+	if req == nil {
+		return m.next.QueryData(ctx, req)
+	}
+
+	m.applyAuthorizationHeader(ctx, req)
+	return m.next.QueryData(ctx, req)
+}
+
+func (m *DatasourceAuthorizationMiddleware) CallResource(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
+	if req == nil {
+		return m.next.CallResource(ctx, req, sender)
+	}
+
+	m.applyAuthorizationHeader(ctx, req)
+	return m.next.CallResource(ctx, req, sender)
+}
+
+func (m *DatasourceAuthorizationMiddleware) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) {
+	if req == nil {
+		return m.next.CheckHealth(ctx, req)
+	}
+
+	m.applyAuthorizationHeader(ctx, req)
+	return m.next.CheckHealth(ctx, req)
+}
+
+func (m *DatasourceAuthorizationMiddleware) CollectMetrics(ctx context.Context, req *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) {
+	return m.next.CollectMetrics(ctx, req)
+}
+
+func (m *DatasourceAuthorizationMiddleware) SubscribeStream(ctx context.Context, req *backend.SubscribeStreamRequest) (*backend.SubscribeStreamResponse, error) {
+	return m.next.SubscribeStream(ctx, req)
+}
+
+func (m *DatasourceAuthorizationMiddleware) PublishStream(ctx context.Context, req *backend.PublishStreamRequest) (*backend.PublishStreamResponse, error) {
+	return m.next.PublishStream(ctx, req)
+}
+
+func (m *DatasourceAuthorizationMiddleware) RunStream(ctx context.Context, req *backend.RunStreamRequest, sender *backend.StreamSender) error {
+	return m.next.RunStream(ctx, req, sender)
+}
diff --git a/pkg/services/pluginsintegration/clientmiddleware/datasource_authorization_middleware_test.go b/pkg/services/pluginsintegration/clientmiddleware/datasource_authorization_middleware_test.go
new file mode 100644
index 0000000..8c78fdc
--- /dev/null
+++ b/pkg/services/pluginsintegration/clientmiddleware/datasource_authorization_middleware_test.go
@@ -0,0 +1,108 @@
+package clientmiddleware
+
+import (
+	"net/http"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+
+	"github.com/grafana/grafana-plugin-sdk-go/backend"
+	"github.com/grafana/grafana/pkg/plugins/manager/client/clienttest"
+	"github.com/grafana/grafana/pkg/services/user"
+)
+
+func TestDatasourceAuthorizationMiddleware(t *testing.T) {
+
+	req, err := http.NewRequest(http.MethodGet, "/some/thing", nil)
+	require.NoError(t, err)
+
+	req.Header.Set("X-Ds-Authorization", "Bearer Token")
+
+	t.Run("Requests are for a datasource", func(t *testing.T) {
+		cdt := clienttest.NewClientDecoratorTest(t,
+			clienttest.WithReqContext(req, &user.SignedInUser{}),
+			clienttest.WithMiddlewares(
+				NewClearAuthHeadersMiddleware(),
+				NewDatasourceAuthorizationMiddleware(),
+			),
+		)
+
+		pluginCtx := backend.PluginContext{
+			DataSourceInstanceSettings: &backend.DataSourceInstanceSettings{},
+		}
+
+		t.Run("Should contain datasource authorization header when calling QueryData", func(t *testing.T) {
+			_, err = cdt.Decorator.QueryData(req.Context(), &backend.QueryDataRequest{
+				PluginContext: pluginCtx,
+			})
+			require.NoError(t, err)
+			require.NotNil(t, cdt.QueryDataReq)
+			require.Len(t, cdt.QueryDataReq.Headers, 1)
+			require.Equal(t, "Bearer Token", cdt.QueryDataReq.GetHTTPHeader("X-Ds-Authorization"))
+		})
+
+		t.Run("Should contain datasource authorization header when calling CallResource", func(t *testing.T) {
+			err = cdt.Decorator.CallResource(req.Context(), &backend.CallResourceRequest{
+				PluginContext: pluginCtx,
+			}, nopCallResourceSender)
+			require.NoError(t, err)
+			require.NotNil(t, cdt.CallResourceReq)
+			require.Len(t, cdt.CallResourceReq.Headers, 1)
+			require.Equal(t, "Bearer Token", cdt.QueryDataReq.GetHTTPHeader("X-Ds-Authorization"))
+		})
+
+		t.Run("Should contain datasource authorization header when calling CheckHealth", func(t *testing.T) {
+			_, err = cdt.Decorator.CheckHealth(req.Context(), &backend.CheckHealthRequest{
+				PluginContext: pluginCtx,
+			})
+			require.NoError(t, err)
+			require.NotNil(t, cdt.CheckHealthReq)
+			require.Len(t, cdt.CheckHealthReq.Headers, 1)
+			require.Equal(t, "Bearer Token", cdt.QueryDataReq.GetHTTPHeader("X-Ds-Authorization"))
+		})
+	})
+
+	t.Run("Requests are for an app", func(t *testing.T) {
+		cdt := clienttest.NewClientDecoratorTest(t,
+			clienttest.WithReqContext(req, &user.SignedInUser{}),
+			clienttest.WithMiddlewares(
+				NewClearAuthHeadersMiddleware(),
+				NewDatasourceAuthorizationMiddleware(),
+			),
+		)
+
+		pluginCtx := backend.PluginContext{
+			AppInstanceSettings: &backend.AppInstanceSettings{},
+		}
+
+		t.Run("Should contain datasource authorization header when calling QueryData", func(t *testing.T) {
+			_, err = cdt.Decorator.QueryData(req.Context(), &backend.QueryDataRequest{
+				PluginContext: pluginCtx,
+			})
+			require.NoError(t, err)
+			require.NotNil(t, cdt.QueryDataReq)
+			require.Len(t, cdt.QueryDataReq.Headers, 1)
+			require.Equal(t, "Bearer Token", cdt.QueryDataReq.GetHTTPHeader("X-Ds-Authorization"))
+		})
+
+		t.Run("Should contain datasource authorization header when calling CallResource", func(t *testing.T) {
+			err = cdt.Decorator.CallResource(req.Context(), &backend.CallResourceRequest{
+				PluginContext: pluginCtx,
+			}, nopCallResourceSender)
+			require.NoError(t, err)
+			require.NotNil(t, cdt.CallResourceReq)
+			require.Len(t, cdt.CallResourceReq.Headers, 1)
+			require.Equal(t, "Bearer Token", cdt.QueryDataReq.GetHTTPHeader("X-Ds-Authorization"))
+		})
+
+		t.Run("Should contain datasource authorization header when calling CheckHealth", func(t *testing.T) {
+			_, err = cdt.Decorator.CheckHealth(req.Context(), &backend.CheckHealthRequest{
+				PluginContext: pluginCtx,
+			})
+			require.NoError(t, err)
+			require.NotNil(t, cdt.CheckHealthReq)
+			require.Len(t, cdt.CheckHealthReq.Headers, 1)
+			require.Equal(t, "Bearer Token", cdt.QueryDataReq.GetHTTPHeader("X-Ds-Authorization"))
+		})
+	})
+}
diff --git a/pkg/services/pluginsintegration/pluginsintegration.go b/pkg/services/pluginsintegration/pluginsintegration.go
index 9b7bcbb..78dbc32 100644
--- a/pkg/services/pluginsintegration/pluginsintegration.go
+++ b/pkg/services/pluginsintegration/pluginsintegration.go
@@ -163,6 +163,7 @@ func CreateMiddlewares(cfg *setting.Cfg, oAuthTokenService oauthtoken.OAuthToken
 		clientmiddleware.NewClearAuthHeadersMiddleware(),
 		clientmiddleware.NewOAuthTokenMiddleware(oAuthTokenService),
 		clientmiddleware.NewCookiesMiddleware(skipCookiesNames),
+		clientmiddleware.NewDatasourceAuthorizationMiddleware(),
 		clientmiddleware.NewResourceResponseMiddleware(),
 	}
